#include "SSPI.h"
#include "Delay.h"
//主机输入引脚
#define SSPI_MISO		 	GPIO_Pin_15 //主机输入口MISO连接的引脚
//主机输出引脚，均为推挽输出
#define SSPI_MOSI 			GPIO_Pin_14 //主机输出口MSOI连接的引脚
#define SSPI_SS 				GPIO_Pin_12   //主机片选CS连接的引脚
#define SSPI_SLK 			GPIO_Pin_13  //主机时钟SLK连接的引脚 
#define SSPI_GPIO_PORT    	GPIOB
//写SS线电平
static void SSPI_W_SS(uint8_t BitValue){
    GPIO_WriteBit(SSPI_GPIO_PORT,SSPI_SS,(BitAction)BitValue);
   // Delay_Us(5);//备用
}

//写SLK线电平
static void SSPI_W_SLK(uint8_t BitValue){
    GPIO_WriteBit(SSPI_GPIO_PORT,SSPI_SLK,(BitAction)BitValue);
    // Delay_Us(5);//备用
}
//写MOSI线电平
static void SSPI_W_MOSI(uint8_t BitValue){
    GPIO_WriteBit(SSPI_GPIO_PORT,SSPI_MOSI,(BitAction)BitValue);
    // Delay_Us(5);//备用
}
//读MISO电平
static uint8_t SSPI_R_MISO(void){
    return GPIO_ReadInputDataBit(SSPI_GPIO_PORT,SSPI_MISO);
}//

void SSPI_Init(void){
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin =SSPI_SLK |SSPI_MOSI|SSPI_SS;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(SSPI_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = SSPI_MISO;
	GPIO_Init(SSPI_GPIO_PORT, &GPIO_InitStructure);

    SSPI_W_SS(1);//ss低电平有效，置1表示不选
    SSPI_W_SLK(0);

}

void SSPI_Start(void){
    SSPI_W_SS(0);//通信开始，拉低SS，选通片
}

void SSPI_Stop(void){
    SSPI_W_SS(1); //通信结束，拉高SS，不选通片
}
//此为模式0，交换一个字节（模式0），若改为模式2，则翻转全部CLK
//模式1和模式3的交换也如此
// CPOL=0：空闲状态时，SCK为低电平
// CPHA=0：SCK第一个边沿移入数据，第二个边沿移出数据

uint8_t SSPI_SwapByte(uint8_t ByteSend)
{
    for (uint8_t i = 0; i < 8; i++) 
    {//第一位数据，在ss下降时，就已经移出
        SSPI_W_MOSI(ByteSend & 0x80); // 时钟下降沿后，主机发送1位数据
        ByteSend<<=1;
        SSPI_W_SLK(1);                // 拉高时钟                    
        ByteSend |= SSPI_R_MISO(); // 上升沿后接受数据，读MISO
        
        SSPI_W_SLK(0); // 拉低时钟,为下一个下降沿做准备
    }
    return ByteSend;
}
